<!DOCTYPE html>












  


<html class="theme-next muse use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2"/>
<meta name="theme-color" content="#222">












<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />






















<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=6.4.0" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=6.4.0">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=6.4.0">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=6.4.0">


  <link rel="mask-icon" href="/images/logo.svg?v=6.4.0" color="#222">









<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Muse',
    version: '6.4.0',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: false,
    fastclick: false,
    lazyload: false,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>


  




  <meta name="description" content="这段时间看了些秒杀业务处理方案，学到了一些东西，可能是比较粗浅的，但是万丈高楼平地起，所以还是做一个记录。 本文内容包括如下几点：  认知中最优的方案。 其他方案以及关联的知识点   学而时习之，不亦乐乎！">
<meta name="keywords" content="seckill">
<meta property="og:type" content="article">
<meta property="og:title" content="秒杀业务的解决方案总结和思考">
<meta property="og:url" content="http://yoursite.com/2018/06/29/seckill-1/index.html">
<meta property="og:site_name" content="ThinkMore">
<meta property="og:description" content="这段时间看了些秒杀业务处理方案，学到了一些东西，可能是比较粗浅的，但是万丈高楼平地起，所以还是做一个记录。 本文内容包括如下几点：  认知中最优的方案。 其他方案以及关联的知识点   学而时习之，不亦乐乎！">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="http://p5h71khzd.bkt.clouddn.com/%E7%A7%92%E6%9D%80%E4%B8%9A%E5%8A%A10630.png">
<meta property="og:updated_time" content="2018-07-09T02:48:36.941Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="秒杀业务的解决方案总结和思考">
<meta name="twitter:description" content="这段时间看了些秒杀业务处理方案，学到了一些东西，可能是比较粗浅的，但是万丈高楼平地起，所以还是做一个记录。 本文内容包括如下几点：  认知中最优的方案。 其他方案以及关联的知识点   学而时习之，不亦乐乎！">
<meta name="twitter:image" content="http://p5h71khzd.bkt.clouddn.com/%E7%A7%92%E6%9D%80%E4%B8%9A%E5%8A%A10630.png">






  <link rel="canonical" href="http://yoursite.com/2018/06/29/seckill-1/"/>



<script type="text/javascript" id="page.configurations">
  CONFIG.page = {
    sidebar: "",
  };
</script>

  <title>秒杀业务的解决方案总结和思考 | ThinkMore</title>
  






  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?13172698bcdb7ab00b7d3ec112aae9c1";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>




  <noscript>
  <style type="text/css">
    .use-motion .motion-element,
    .use-motion .brand,
    .use-motion .menu-item,
    .sidebar-inner,
    .use-motion .post-block,
    .use-motion .pagination,
    .use-motion .comments,
    .use-motion .post-header,
    .use-motion .post-body,
    .use-motion .collection-title { opacity: initial; }

    .use-motion .logo,
    .use-motion .site-title,
    .use-motion .site-subtitle {
      opacity: initial;
      top: initial;
    }

    .use-motion {
      .logo-line-before i { left: initial; }
      .logo-line-after i { right: initial; }
    }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">ThinkMore</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
    
      
        <p class="site-subtitle">驽马十驾,功在不舍！</p>
      
    
  </div>

  <div class="site-nav-toggle">
    <button aria-label="Toggle navigation bar">
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>



<nav class="site-nav">
  
    <ul id="menu" class="menu">
      
        
        
        
          
          <li class="menu-item menu-item-home">
    <a href="/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-home"></i> <br />Home</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-archives">
    <a href="/archives/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />Archives</a>
  </li>

      
      
    </ul>
  

  
    

  

  
</nav>



  



</div>
    </header>

    


    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/06/29/seckill-1/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="文敦复">
      <meta itemprop="description" content="思考的懒惰是真的懒惰！">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="ThinkMore">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">秒杀业务的解决方案总结和思考
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">

            
            
            

            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">Posted on</span>
              

              
                
              

              <time title="Created: 2018-06-29 23:39:30" itemprop="dateCreated datePublished" datetime="2018-06-29T23:39:30+08:00">2018-06-29</time>
            

            
              

              
                
                <span class="post-meta-divider">|</span>
                

                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                
                  <span class="post-meta-item-text">Edited on</span>
                
                <time title="Modified: 2018-07-09 10:48:36" itemprop="dateModified" datetime="2018-07-09T10:48:36+08:00">2018-07-09</time>
              
            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">In</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/解决方案/" itemprop="url" rel="index"><span itemprop="name">解决方案</span></a></span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>这段时间看了些秒杀业务处理方案，学到了一些东西，可能是比较粗浅的，但是万丈高楼平地起，所以还是做一个记录。</p>
<p>本文内容包括如下几点：</p>
<ol>
<li>认知中最优的方案。</li>
<li>其他方案以及关联的知识点</li>
</ol>
<blockquote>
<p>学而时习之，不亦乐乎！</p>
</blockquote>
<a id="more"></a>
<h1 id="Redis-MQ保证：可能最优的方案"><a href="#Redis-MQ保证：可能最优的方案" class="headerlink" title="Redis+MQ保证：可能最优的方案"></a>Redis+MQ保证：可能最优的方案</h1><ol>
<li>秒杀业务前，将秒杀商品和库存信息缓存到<code>Redis</code>中。</li>
<li>在<code>Nginx</code>、<code>Tomcat</code>等处通过<code>令牌桶</code>进行限流处理。</li>
<li>请求到达服务方法后判定<code>商品售卖完成缓存</code>中是否存在当前商品，如果不存在继续往下。</li>
<li>对<code>Redis</code>中缓存的商品数量做<code>decr</code>减1操作，如果小于0则将商品id加入<code>商品售卖完成缓存</code>中。避免每次都往Redis请求。</li>
<li>如果Redis做<code>decr</code>后大于0，则进行秒杀。</li>
<li>将订单信息通过<code>MQ</code>异步下单，通知后续业务。</li>
<li>后续业务就是正常的建立订单等业务。</li>
</ol>
<p><img src="http://p5h71khzd.bkt.clouddn.com/%E7%A7%92%E6%9D%80%E4%B8%9A%E5%8A%A10630.png" alt="秒杀业务"></p>
<p>关于上述方案的几点说明</p>
<ol>
<li>秒杀商品的信息可以优先加载到缓存中。</li>
<li>发现商品售卖完成后，在本地建立商品售卖完成的缓存，避免每次都将请求发送到Redis做判定。</li>
<li>不应该是获取Redis中某商品的库存，然后再判定下单，而是在Redis中减少库存后做判定。因为直接通过Java代码查看库存，判定库存，减少库存是不具有原子性的，除非加分布式锁，但是意义不大。</li>
<li>秒杀后通过MQ异步下单</li>
<li>防止超卖其实是Redis的单线程特性的功劳。</li>
</ol>
<blockquote>
<p>本方案中中间件为 Redis和MQ。 Redis防止超卖 MQ异步下单。</p>
</blockquote>
<h1 id="非Redis方案"><a href="#非Redis方案" class="headerlink" title="非Redis方案"></a>非Redis方案</h1><p>以下的方案重点在于防止超卖，库存信息不加载到缓存Redis，而是直接同DB交互，实际场景下不会如此，但是其中用到的细节还是值得学习的。</p>
<h2 id="for-update"><a href="#for-update" class="headerlink" title="for update"></a>for update</h2><p>该方案通过<code>事务+for update</code>进行保证，伪代码如下所示：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">begin transcational</span><br><span class="line">count =  SELECT number FROM seckill WHERE seckill_id=? FOR UPDATE</span><br><span class="line"><span class="keyword">if</span> count &gt; <span class="number">0</span></span><br><span class="line">UPDATE seckill  SET number=number-<span class="number">1</span> WHERE seckill_id=?</span><br><span class="line">INSERT order <span class="comment">//下订单</span></span><br><span class="line">commit</span><br></pre></td></tr></table></figure>
<p>说明：</p>
<ol>
<li>同一个事务中 如果查询最后限定了 <code>for update</code> 那么非本次事务中的 其他SQL指令会被阻塞。如果where条件为主键或者索引列的时候才会锁住行，否则会所表，当前的where条件很明确是<code>seckill_id</code>为主键，所以是行级锁。</li>
<li>select操作和update操作都是在本次事务中进行的。</li>
</ol>
<h2 id="库存大于0判定"><a href="#库存大于0判定" class="headerlink" title="库存大于0判定"></a>库存大于0判定</h2><p>该方案主要通过在执行update减少库存的时候，加上对库存大于0的判定。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">begin transcational</span><br><span class="line">count = UPDATE seckill  SET number=number-<span class="number">1</span> WHERE seckill_id=? AND number&gt;<span class="number">0</span></span><br><span class="line"><span class="keyword">if</span> count &gt; <span class="number">0</span></span><br><span class="line">INSERT order <span class="comment">//下订单</span></span><br><span class="line">commit</span><br></pre></td></tr></table></figure>
<p>其中最为核心的就是最后一个条件<code>number&gt;0</code></p>
<h2 id="分布式锁"><a href="#分布式锁" class="headerlink" title="分布式锁"></a>分布式锁</h2><p>通过分布式锁来保证，同一时间只会有一个线程在处理某类商品秒杀业务：查询库存–&gt;判定库存 –&gt;减少库存。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">dis-lock goods type <span class="comment">//1. 通过分布式锁:锁住商品类型</span></span><br><span class="line">begin transcational <span class="comment">//2. 开启事务</span></span><br><span class="line">count =  SELECT number FROM seckill WHERE seckill_id=? </span><br><span class="line"><span class="keyword">if</span> count &gt; <span class="number">0</span></span><br><span class="line">UPDATE seckill  SET number=number-<span class="number">1</span> WHERE seckill_id=?</span><br><span class="line">INSERT order <span class="comment">//下订单</span></span><br><span class="line"><span class="comment">// dis-un-lock goods type 错误释放分布式锁</span></span><br><span class="line">commit <span class="comment">//3. 提交事务</span></span><br><span class="line">dis-un-lock goods type <span class="comment">//4. 释放分布式锁</span></span><br></pre></td></tr></table></figure>
<p>说明</p>
<ol>
<li><p>请注意3和4 的顺序，一定要先提交事务后，再释放分布式锁。</p>
<p>为什么了？假设此时的库存为1。第一个线程在第提交事务前释放了锁，假设提交事务需要5个单位的时间。另外一个线程在第一个线程释放锁的瞬间，抢占了锁，然后在3个时间就完成了查询和减少库存并提交事务的操作，此时库存为0。2个单位后第一个线程事务提交才完成，此时库存为-1了。这样导致了超卖。</p>
<p>所以事务的提交一定要释放分布式锁之前。</p>
</li>
<li><p>在Spring中事务通过是通过注解<code>@Transcational</code>来实现的，如果直接在<code>@Transcational</code>包裹的方法里面获取锁和释放锁可能会出现超卖，此时需要通过另外一个AOP进行包装，这里涉及到2个知识点。</p>
<p>一是：一个方法有多个AOP注解时候，切面的执行顺序怎么确定的问题。该问题是每个切面都可以通过<code>@order</code>来定义顺序，越小的越先执行，而<code>@Transcational</code>的order是最大，所以肯定是在内部执行。</p>
<p>二是：多个切面的执行顺序和退出顺序问题，可以参考此文：<a href="http://www.hicode.club/2018/03/01/apsect-order/" target="_blank" rel="noopener">http://www.hicode.club/2018/03/01/apsect-order/</a></p>
</li>
</ol>
<h2 id="乐观锁"><a href="#乐观锁" class="headerlink" title="乐观锁"></a>乐观锁</h2><p>通过乐观锁来保证商品在每一个只会被消费一次，<del>此时需要在秒杀表中添加一个版本号字段。</del>  通过对<code>number</code>进行乐观锁来进行判定，伪代码如下所示：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">begin transcational</span><br><span class="line">n = select googs number</span><br><span class="line">count = UPDATE seckill SET number=number-<span class="number">1</span> WHERE seckill_id=? AND number = n</span><br><span class="line"><span class="keyword">if</span> count &gt; <span class="number">0</span></span><br><span class="line">INSERT order <span class="comment">//下订单</span></span><br><span class="line">commit</span><br></pre></td></tr></table></figure>
<p>说明</p>
<ol>
<li>请注意每次进行update前先查询，查询的目的是获取版本号。</li>
<li>通过对CAS的思想通过版本号对库存进行更新，如果符合预期那么更新，否则肯定是被其他线程消费过。</li>
</ol>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>技术是为了解决业务难题而存在和发展的，切记脱离业务来学习技术。</p>
<p>上述方案都是解决秒杀业务的初步原形，大概思路如上所述，其中其实有很多细节，后续抽时间补上。</p>
<p>业务处理上需要结合自己的业务进行扩展，个人推荐：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">redis &gt; 乐观锁 &gt; 库存大于<span class="number">0</span> &gt; 分布式锁 &gt; <span class="keyword">for</span> update</span><br></pre></td></tr></table></figure>
<ol>
<li>原则上尽可能的避免锁表操作。</li>
<li>尽量避免请求直接打到数据库上。</li>
</ol>
<blockquote>
<p>您有任何建议和意见，请Email联系: <a href="mailto:hicode_club@163.com" target="_blank" rel="noopener">hicode_club@163.com</a></p>
<p>转载请保留出处 <a href="http://www.hicode.club" target="_blank" rel="noopener">HiCode 俱乐部</a></p>
</blockquote>

      
    </div>

    

    
    
    

    

    

    

    <footer class="post-footer">
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2018/06/28/thread-pool-mix/" rel="next" title="Java线程池的综合知识点">
                <i class="fa fa-chevron-left"></i> Java线程池的综合知识点
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2018/06/30/rpc-mock/" rel="prev" title="RPC的Mock方案总结">
                RPC的Mock方案总结 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>


  </div>


          </div>
          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            Table of Contents
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            Overview
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">文敦复</p>
              <p class="site-description motion-element" itemprop="description">思考的懒惰是真的懒惰！</p>
          </div>

          
            <nav class="site-state motion-element">
              
                <div class="site-state-item site-state-posts">
                
                  <a href="/archives/">
                
                    <span class="site-state-item-count">39</span>
                    <span class="site-state-item-name">posts</span>
                  </a>
                </div>
              

              
                
                
                <div class="site-state-item site-state-categories">
                  
                    
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                    <span class="site-state-item-count">37</span>
                    <span class="site-state-item-name">categories</span>
                  
                </div>
              

              
            </nav>
          

          

          

          
          

          
          

          
            
          
          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#Redis-MQ保证：可能最优的方案"><span class="nav-number">1.</span> <span class="nav-text">Redis+MQ保证：可能最优的方案</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#非Redis方案"><span class="nav-number">2.</span> <span class="nav-text">非Redis方案</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#for-update"><span class="nav-number">2.1.</span> <span class="nav-text">for update</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#库存大于0判定"><span class="nav-number">2.2.</span> <span class="nav-text">库存大于0判定</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#分布式锁"><span class="nav-number">2.3.</span> <span class="nav-text">分布式锁</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#乐观锁"><span class="nav-number">2.4.</span> <span class="nav-text">乐观锁</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#总结"><span class="nav-number">3.</span> <span class="nav-text">总结</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2018</span>
  <span class="with-love" id="animate">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">文敦复</span>

  

  
</div>




  <div class="powered-by">Powered by <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> v3.7.1</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">Theme – <a class="theme-link" target="_blank" href="https://theme-next.org">NexT.Muse</a> v6.4.0</div>




        








        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    
	
    

    
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>


























  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=6.4.0"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=6.4.0"></script>



  
  

  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=6.4.0"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=6.4.0"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=6.4.0"></script>



  



  










  





  

  

  

  

  
  

  

  

  

  

  

</body>
</html>
